﻿/********************************\
 * C# 配置文件读写模块
 * 版本 1.4
\********************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;

namespace DeskFund
{
    public class IniHelper
    {
        public static string ConfigFileName = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + "\\Config.ini";
        private static int BUFFER_SIZE = 65536 * 2;

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        #region 通用读写配置文件，需要指定文件
        /// <summary>
        /// 通用写入配置文件
        /// </summary>
        /// <param name="section">配置节点所属的分类段</param>
        /// <param name="key">配置节点的名称</param>
        /// <param name="value">配置节点的值</param>
        /// <param name="filepath">要保存的配置文件路径</param>
        public static void WriteValue(string section, string key, string value, string filepath)
        {
            WritePrivateProfileString(section, key, value, filepath);
        }

        /// <summary>
        /// 通用读取配置文件
        /// </summary>
        /// <param name="section">配置节点所属的分类段</param>
        /// <param name="key">配置节点的名称</param>
        /// <param name="filepath">要读取的配置文件路径</param>
        /// <returns>返回配置节点的值</returns>
        public static string ReadValue(string section, string key, string filepath)
        {
            StringBuilder temp = new StringBuilder(BUFFER_SIZE);
            int i = GetPrivateProfileString(section, key, "", temp, BUFFER_SIZE, filepath);
            return temp.ToString();
        }
        #endregion

        #region 读写默认文件
        /// <summary>
        /// 写入默认的配置文件Config.ini
        /// </summary>
        /// <param name="section">配置节点所属的分类段</param>
        /// <param name="key">配置节点的名称</param>
        /// <param name="value">配置节点的值</param>
        public static void WriteValue(string section, string key, string value)
        {
            WritePrivateProfileString(section, key, value, ConfigFileName);
        }

        /// <summary>
        /// 读取默认的配置文件Config.ini
        /// </summary>
        /// <param name="section">配置节点所属的分类段</param>
        /// <param name="key">配置节点的名称</param>
        /// <returns>返回配置节点的值</returns>
        public static string ReadValue(string section, string key)
        {
            StringBuilder temp = new StringBuilder(BUFFER_SIZE);
            int i = GetPrivateProfileString(section, key, "", temp, BUFFER_SIZE, ConfigFileName);
            return temp.ToString();
        }
        #endregion

        #region 读写默认文件中的默认节点
        /// <summary>
        /// 写入默认的配置文件Config.ini中的默认节点[Config]
        /// </summary>
        /// <param name="key">配置节点的名称</param>
        /// <param name="value">配置节点的值</param>
        public static void WriteValue(string key, string value)
        {
            WritePrivateProfileString("Config", key, value, ConfigFileName);
        }

        /// <summary>
        /// 读取默认的配置文件Config.ini中的默认节点[Config]
        /// </summary>
        /// <param name="key">配置节点的名称</param>
        /// <returns>返回配置节点的值</returns>
        public static string ReadValue(string key)
        {
            StringBuilder temp = new StringBuilder(BUFFER_SIZE);
            int i = GetPrivateProfileString("Config", key, "", temp, BUFFER_SIZE, ConfigFileName);
            return temp.ToString();
        }
        #endregion

        #region 加密读写默认文件
        /// <summary>
        /// 加密写入配置文件
        /// </summary>
        /// <param name="section">配置节点所属的分类段</param>
        /// <param name="key">配置节点的名称</param>
        /// <param name="value">配置节点的值</param>
        /// <param name="filepath">要保存的配置文件路径</param>
        /// <param name="cypher">密钥</param>
        public static void WriteValue(string section, string key, string value, string filepath, string cypher)
        {
            string encValue = EncryptClass.Encrypt3DES(value, cypher);

            WritePrivateProfileString(section, key, encValue, filepath);
        }

        /// <summary>
        /// 读取配置文件并解密
        /// </summary>
        /// <param name="section">配置节点所属的分类段</param>
        /// <param name="key">配置节点的名称</param>
        /// <returns>返回配置节点的值</returns>
        /// <param name="filepath">要保存的配置文件路径</param>
        /// <param name="cypher">密钥</param>
        public static string ReadValue(string section, string key, string filepath, string cypher)
        {
            StringBuilder temp = new StringBuilder(BUFFER_SIZE);
            int i = GetPrivateProfileString(section, key, "", temp, BUFFER_SIZE, filepath);

            string decValue = EncryptClass.Decrypt3DES(temp.ToString(), cypher);
            return decValue;
        }
        #endregion
    }

    public class EncryptClass
    {
        #region MD5加密
        /// <summary>
        /// MD5加密16位(加密过程不可逆)
        /// </summary>
        /// <param name="convertString">要加密的字符串</param>
        /// <returns>加密后的字符串</returns>
        public static string MD516(string convertString)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(convertString)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2;
        }

        /// <summary>
        /// MD5加密32位(加密过程不可逆)
        /// </summary>
        /// <param name="convertString">要加密的字符串</param>
        /// <returns>加密后的字符串</returns>
        public static string MD532(string convertString)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] hash;
            hash = md5.ComputeHash(Encoding.UTF8.GetBytes(convertString));
            md5.Clear();
            string temp = "";
            for (int i = 0; i < hash.Length; i++)
            {
                temp += hash[i].ToString("x").PadLeft(2, '0');
            }
            return temp;
        }
        #endregion

        #region 3Des加密和解密
        /// <summary>
        /// 3DES加密
        /// </summary>
        /// <param name="plaintext"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string Encrypt3DES(string plaintext, string key)
        {
            key = MD532(key).Substring(0, 24);

            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.ECB;

            ICryptoTransform DESEncrypt = DES.CreateEncryptor();

            byte[] buffer = Encoding.Default.GetBytes(plaintext);
            return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length));
        }

        /// <summary>
        /// 3DES解密
        /// </summary>
        /// <param name="encrypttext"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string Decrypt3DES(string encrypttext, string key)
        {
            key = MD532(key).Substring(0, 24);
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.ECB;
            DES.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

            ICryptoTransform DESDecrypt = DES.CreateDecryptor();

            string result = "";
            try
            {
                byte[] buffer = Convert.FromBase64String(encrypttext);
                result = Encoding.Default.GetString(DESDecrypt.TransformFinalBlock(buffer, 0, buffer.Length));
            }
            catch { }

            return result;
        }
        #endregion
    }
}